﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;
using FinPlusAssembler;
using FinPlusInterfaces;
using Microsoft.Win32;

namespace FinPlusCompView
{
    public partial class FinPlusDiagnostic : FinPlusControl
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Save = true)]
        public new double Height { get { return base.Height; } set { base.Height = value; } }
        [State(Save = true)]
        public new double Width { get { return base.Width; } set { base.Width = value; } }
        [State(Save = true)]
        public string FilePath { get { return _filePath; } set { _filePath = value; tFile.Text = _filePath; } }
        [State(Save = true)]
        public string InfoState { get { return GetInfoState(); } set { SetInfoState(value); } }
        [State(Save = true)]
        public string TargetType { get { return fileType.Text; } set { _targetType = value.EnumParse<FileType>(FileType.view); fileType.Text = value; } }
        [State(Save = true)]
        public double EditorWidth { get { return editorCol.Width.Value; } set { editorCol.Width = new GridLength(value); } }
        [State(Save = true)]
        public double EditorHeight { get { return editorRow.Height.Value; } set { editorRow.Height = new GridLength(value); } }

        private IPod _infos;
        private IPods _target;
        private FileType _targetType;
        private Assembly _targetAssembly;
        private string _filePath, _infoPath, _targetName;
  
        //construct
        public FinPlusDiagnostic()
        {
            InitializeComponent();
            _target = IOC.New<IPods>();
            fileType.ItemsSource = Enum.GetValues(typeof(FileType)).Cast<FileType>();
            fileType.SelectedItem = FileType.view;
            IsValid = true;
        }

        //common control interface
        public override void CmdExecute(IPod command)
        {
            try
            {
                CmdCapture(command);

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.Refresh: FileConnect(tFile.Text); break;
                    case Cmds.Cancel: Clear(); break;
                    case Cmds.Diagnose: Diagnose(); break;
                    case Cmds.Stop: ClearChildren(); break;
                    case Cmds.FileRouter: FileRouter(); break;
                    case Cmds.File: FileLoad(command["Tag"].ToString()); break;
                    default: throw new Exception(string.Format("cmd not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
                IsValid = Level.Warning.Log(Id, Config, e.Message, e);
            }
        }

        public override void Dispose()  
        {
            if(_target != null)
                DI.Dispose(_target.Id);
        }

        //private
        private void AddConnection(IFinPlusComp conn)
        {
            try
            {
                Clear();
                _target = conn.Adapter;
                xmlLayout.xmlDocument = _target.ToXmlDoc();
                ShowInfos(_target, _targetAssembly);
            }
            catch (Exception e)
            {
                IsValid = Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        private void ClearChildren()
        {
            testSubject.Text = "";
            gridUI.Children.Clear();
        }

        private void Diagnose()
        {
            try
            {
                if (string.IsNullOrEmpty(_filePath)) 
                    return;

                gridUI.Children.Clear();
                _targetName = _filePath.Split('\\').Last();
                _targetType =   fileType.Text.Split('.').Last().EnumParse<FileType>();
                _targetAssembly = _targetType == FileType.view ? Assembly.GetExecutingAssembly() :
                    Assembly.LoadFile(Paths.Values["FolderRoot"] + "FinPlusCompCore.dll");

                DI.Dispose(_target.Id);
                var control = _target.Construct(_targetName.Split('.')[0], Env.dev);

                ShowInfos(_target, _targetAssembly);
                if (_targetType == FileType.service)
                    ShowService(control);
                else if (_targetType == FileType.view)
                    ShowView(control);

                testSubject.Text = _targetName;
            }
            catch (Exception e)
            {
                IsValid = Level.Warning.Log(Id, Config, e.Message, e);
            }
        }

        private void ShowInfos(IPods infos, Assembly target)
        {
            var path = Paths.Values["FolderSubViews"] + "DiagnosticInfos.view";
            _infos = IOC.New<IPods>(path).Construct("DiagnosticInfos", Env, new object[,] { { "Data", IOC.New<IDPods>(infos.Get(target)) } });
            SetInfoState(_infoPath);

            gridInfos.Children.Add((FinPlusGroupGrid)_infos.Object);
        }

        private void ShowService(IPod pod)
        {
            var path = Paths.Values["FolderSubViews"] + "DiagnosticService.view";
            var service = IOC.New<IPods>(path).Construct("Infos", Env, new object[,] { { "Data", IOC.New<IDPods>(((IFinPlusComp)pod.Object).Adapter) } });
            
            gridUI.Children.Add((FinPlusGroupGrid)service.Object);
        }

        private void ShowView(IPod pod)
        {
            pod.InjectState(_filePath.Split('.')[0]);
            gridUI.Children.Add((UserControl)pod.Object);
        }

        private string GetInfoState()
        {
            if (_infos == null) 
                return string.Empty;

            var path = Paths.Values["FolderSubViews"] + "InfoState";
            _infos.ExtractState(Environment.UserName).ToXmlDoc().Save(path + "." + FileType.state.ToString()); 
            
            return path;
        }

        private void SetInfoState(string path)
        {
            if (!string.IsNullOrEmpty(path))
                _infos.InjectState(_infoPath = path);
        }

        private void FileLoad(string path)
        {
            tFile.Text = _filePath = path;
            FileConnect(tFile.Text);
        }

        private void FileConnect(string path)
        {
            var service = new FinPlusConnectXML(path);
            AddConnection(service);
        }

        private void Clear()
        {
            try
            {
                xmlLayout.xmlDocument = null;
                gridUI.Children.Clear();
                
                ShowInfos(_target, _targetAssembly);
            }
            catch (Exception e)
            {
               IsValid =  Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        private void FileRouter()
        {
            gridUI.Children.Clear();
            var d = new OpenFileDialog()
            {
                FileName = "Document",
                DefaultExt = "." + fileType.SelectedItem,
                Filter = string.Format("{0} documents (.{0})|*.{0}", fileType.SelectedItem)
            };
            var res = d.ShowDialog();

            if (res == true)
                CmdRouter(Cmds.File.ToString(), d.FileName);
        }

        //cmds
        private enum Cmds { Refresh, Cancel, Diagnose, Stop, FileRouter, File }
    }
}





























































































//Copyright2013<jnrton>AllRightsReserved 
//Contact j.nrton@finpus